#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <ifaddrs.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/aes.h>
#include <stdio.h>

#include "cJSON.h"
#include "base64.h"
#define AES_BLOCK_SIZE  16

unsigned char   data_downmode[98]   = {0};


typedef struct custom
{
	int soak_water_level ; //      24200
	int soak_time ; //      0
	int wash_water_level ; //      24200
	int wash_temp ; //      40

	int wash_1_off_time ; //      10
	int wash_1_on_time ; //      10
	int wash_1_time ; //      3
	int wash_1_speed ; //      55

	int wash_2_off_time ; //      15
	int wash_2_on_time ; //      20
	int wash_2_time ; //      10
	int wash_2_speed ; //      55

	int wash_3_off_time ; //      20
	int wash_3_on_time ; //      15
	int wash_3_time ; //      1
	int wash_3_speed ; //      55

	int rinse_times ; //      3

	int rinse_water_level_1 ; //      24000
	int rinse_speed_1 ; //      700
	int rinse_on_time_1 ; //      15
	int rinse_off_time_1 ; //      10
	int rinse_time_1 ; //      120
	int rinse_isSpin_1 ; //      1
	int dehydrate_top_speed_1 ; //      700
	int dehydrate_keep_time_1 ; //      60

	int rinse_water_level_2 ; //      24000
	int rinse_speed_2 ; //      50
	int rinse_on_time_2 ; //      15
	int rinse_off_time_2 ; //      10
	int rinse_time_2 ; //      120
	int rinse_isSpin_2 ; //      1
	int dehydrate_top_speed_2 ; //      700
	int dehydrate_keep_time_2 ; //      60

	int rinse_water_level_3 ; //      24000
	int rinse_speed_3 ; //      50
	int rinse_on_time_3 ; //      15
	int rinse_off_time_3 ; //      10
	int rinse_time_3 ; //      120
	int rinse_isSpin_3 ; //      1
	int dehydrate_top_speed_3 ; //      700
	int dehydrate_keep_time_3 ; //      60

	int rinse_water_level_4 ; //      24000
	int rinse_speed_4 ; //      50
	int rinse_on_time_4 ; //      15
	int rinse_off_time_4 ; //      10
	int rinse_time_4 ; //      120
	int rinse_isSpin_4 ; //      1
	int dehydrate_top_speed_4 ; //      700
	int dehydrate_keep_time_4 ; //      60

	int rinse_water_level_5 ; //      24000
	int rinse_speed_5 ; //      50
	int rinse_on_time_5 ; //      15
	int rinse_off_time_5 ; //      20
	int rinse_time_5 ; //      120
	int rinse_isSpin_5 ; //      1

	int dehydrate_top_speed_5 ; //      700
	int dehydrate_keep_time_5 ; //      60

	int dehydrate_top_speed_in_wash ; //      700
	int dehydrate_keep_time_in_wash ; //      60

	int dehydrate_top_speed_in_final ; //      700
	int dehydrate_keep_time_in_final ; //      120

	// int heatingOnTime ; //      250
	int deploy_time ; //      30
	int heatingOnTime ; //      250
	int door_wash_time ; //      4

	int isDehydrate ; //      1
	int isDehydrateFinal ; //      1

	int Spin_time ; //      0
	int Spin_speed ; //      0
	int Spin_mid_time ; //      0
}CUSTOM;



int set_mode_down(unsigned char *mode_json)
{
    // int count = mode_down(mode_json);


    CUSTOM obj;

    cJSON *pJson = cJSON_Parse(mode_json);
    if(pJson==NULL)
    {
        printf(">>> get mode NULL json\n");
        return -1;
    }
    

    cJSON *psoak_water_level = cJSON_GetObjectItem(pJson,"soak_water_level");
    obj.soak_water_level = psoak_water_level->valueint;

    cJSON *psoak_time = cJSON_GetObjectItem(pJson,"soak_time");
    obj.soak_time = psoak_time->valueint;

    cJSON *pwash_water_level = cJSON_GetObjectItem(pJson,"wash_water_level");
    obj.wash_water_level = pwash_water_level->valueint;
    
    cJSON *pwash_temp = cJSON_GetObjectItem(pJson,"wash_temp");
    obj.wash_temp = pwash_temp->valueint;
    
    cJSON *pwash_1_off_time = cJSON_GetObjectItem(pJson,"wash_1_off_time");
    obj.wash_1_off_time = pwash_1_off_time->valueint;

    cJSON *pwash_1_on_time = cJSON_GetObjectItem(pJson,"wash_1_on_time");
    obj.wash_1_on_time = pwash_1_on_time->valueint;

    cJSON *pwash_1_time = cJSON_GetObjectItem(pJson,"wash_1_time");
    obj.wash_1_time = pwash_1_time->valueint;

    cJSON *pwash_1_speed = cJSON_GetObjectItem(pJson,"wash_1_speed");
    obj.wash_1_speed = pwash_1_speed->valueint;

    cJSON *pwash_2_off_time = cJSON_GetObjectItem(pJson,"wash_2_off_time");
    obj.wash_2_off_time = pwash_2_off_time->valueint;

    cJSON *pwash_2_on_time = cJSON_GetObjectItem(pJson,"wash_2_on_time");
    obj.wash_2_on_time = pwash_2_on_time->valueint;

    cJSON *pwash_2_time = cJSON_GetObjectItem(pJson,"wash_2_time");
    obj.wash_2_time = pwash_2_time->valueint;

    cJSON *pwash_2_speed = cJSON_GetObjectItem(pJson,"wash_2_speed");
    obj.wash_2_speed = pwash_2_speed->valueint;

    cJSON *pwash_3_off_time = cJSON_GetObjectItem(pJson,"wash_3_off_time");
    obj.wash_3_off_time = pwash_3_off_time->valueint;

    cJSON *pwash_3_on_time = cJSON_GetObjectItem(pJson,"wash_3_on_time");
    obj.wash_3_on_time = pwash_3_on_time->valueint;

    cJSON *pwash_3_time = cJSON_GetObjectItem(pJson,"wash_3_time");
    obj.wash_3_time = pwash_3_time->valueint;

   cJSON *pwash_3_speed = cJSON_GetObjectItem(pJson,"wash_3_speed");
    obj.wash_3_speed = pwash_3_speed->valueint;

    cJSON *prinse_times = cJSON_GetObjectItem(pJson,"rinse_times");
    obj.rinse_times = prinse_times->valueint;

    cJSON *prinse_water_level_1 = cJSON_GetObjectItem(pJson,"rinse_water_level_1");
    obj.rinse_water_level_1 = prinse_water_level_1->valueint;

    cJSON *prinse_speed_1 = cJSON_GetObjectItem(pJson,"rinse_speed_1");
    obj.rinse_speed_1 = prinse_speed_1->valueint;

    cJSON *prinse_on_time_1 = cJSON_GetObjectItem(pJson,"rinse_on_time_1");
    obj.rinse_on_time_1 = prinse_on_time_1->valueint;

    cJSON *prinse_off_time_1 = cJSON_GetObjectItem(pJson,"rinse_off_time_1");
    obj.rinse_off_time_1 = prinse_off_time_1->valueint;

    cJSON *prinse_time_1 = cJSON_GetObjectItem(pJson,"rinse_time_1");
    obj.rinse_time_1 = prinse_time_1->valueint;

    cJSON *prinse_isSpin_1 = cJSON_GetObjectItem(pJson,"rinse_isSpin_1");
    obj.rinse_isSpin_1 = prinse_isSpin_1->valueint;

    cJSON *pdehydrate_top_speed_1 = cJSON_GetObjectItem(pJson,"dehydrate_top_speed_1");
    obj.dehydrate_top_speed_1 = pdehydrate_top_speed_1->valueint;

    cJSON *pdehydrate_keep_time_1 = cJSON_GetObjectItem(pJson,"dehydrate_keep_time_1");
    obj.dehydrate_keep_time_1 = pdehydrate_keep_time_1->valueint;

    cJSON *prinse_water_level_2 = cJSON_GetObjectItem(pJson,"rinse_water_level_2");
    obj.rinse_water_level_2 = prinse_water_level_2->valueint;

    cJSON *prinse_speed_2 = cJSON_GetObjectItem(pJson,"rinse_speed_2");    
    obj.rinse_speed_2 = prinse_speed_2->valueint;

    cJSON *prinse_on_time_2 = cJSON_GetObjectItem(pJson,"rinse_on_time_2"); 
    obj.rinse_on_time_2 = prinse_on_time_2->valueint;

    cJSON *prinse_off_time_2 = cJSON_GetObjectItem(pJson,"rinse_off_time_2"); 
    obj.rinse_off_time_2 = prinse_off_time_2->valueint;

    cJSON *prinse_time_2 = cJSON_GetObjectItem(pJson,"rinse_time_2"); 
    obj.rinse_time_2 = prinse_time_2->valueint;

    cJSON *prinse_isSpin_2 = cJSON_GetObjectItem(pJson,"rinse_isSpin_2"); 
    obj.rinse_isSpin_2 = prinse_isSpin_2->valueint;

    cJSON *pdehydrate_top_speed_2 = cJSON_GetObjectItem(pJson,"dehydrate_top_speed_2");  
    obj.dehydrate_top_speed_2 = pdehydrate_top_speed_2->valueint;

    cJSON *pdehydrate_keep_time_2 = cJSON_GetObjectItem(pJson,"dehydrate_keep_time_2");  
    obj.dehydrate_keep_time_2 = pdehydrate_keep_time_2->valueint;

    cJSON *prinse_water_level_3 = cJSON_GetObjectItem(pJson,"rinse_water_level_3");  
    obj.rinse_water_level_3 = prinse_water_level_3->valueint;

    cJSON *prinse_speed_3 = cJSON_GetObjectItem(pJson,"rinse_speed_3");  
    obj.rinse_speed_3 = prinse_speed_3->valueint;

    cJSON *prinse_on_time_3 = cJSON_GetObjectItem(pJson,"rinse_on_time_3"); 
    obj.rinse_on_time_3 = prinse_on_time_3->valueint;

    cJSON *prinse_off_time_3 = cJSON_GetObjectItem(pJson,"rinse_off_time_3"); 
    obj.rinse_off_time_3 = prinse_off_time_3->valueint;

    cJSON *prinse_time_3 = cJSON_GetObjectItem(pJson,"rinse_time_3"); 
    obj.rinse_time_3 = prinse_time_3->valueint;

    cJSON *prinse_isSpin_3 = cJSON_GetObjectItem(pJson,"rinse_isSpin_3"); 
    obj.rinse_isSpin_3 = prinse_isSpin_3->valueint;

    cJSON *pdehydrate_top_speed_3 = cJSON_GetObjectItem(pJson,"dehydrate_top_speed_3"); 
    obj.dehydrate_top_speed_3 = pdehydrate_top_speed_3->valueint;

    cJSON *pdehydrate_keep_time_3 = cJSON_GetObjectItem(pJson,"dehydrate_keep_time_3"); 
    obj.dehydrate_keep_time_3 = pdehydrate_keep_time_3->valueint;

    cJSON *prinse_water_level_4 = cJSON_GetObjectItem(pJson,"rinse_water_level_4");
    obj.rinse_water_level_4 = prinse_water_level_4->valueint;

     cJSON *prinse_speed_4 = cJSON_GetObjectItem(pJson,"rinse_speed_4");
    obj.rinse_speed_4 = prinse_speed_4->valueint;

    cJSON *prinse_on_time_4 = cJSON_GetObjectItem(pJson,"rinse_on_time_4");
    obj.rinse_on_time_4 = prinse_on_time_4->valueint;

    cJSON *prinse_off_time_4 = cJSON_GetObjectItem(pJson,"rinse_off_time_4");
    obj.rinse_off_time_4 = prinse_off_time_4->valueint;


    cJSON *prinse_time_4 = cJSON_GetObjectItem(pJson,"rinse_time_4");
    obj.rinse_time_4 = prinse_time_4->valueint;

    cJSON *prinse_isSpin_4 = cJSON_GetObjectItem(pJson,"rinse_isSpin_4");
    obj.rinse_isSpin_4 = prinse_isSpin_4->valueint;

    cJSON *pdehydrate_top_speed_4 = cJSON_GetObjectItem(pJson,"dehydrate_top_speed_4");
    obj.dehydrate_top_speed_4 = pdehydrate_top_speed_4->valueint;

    cJSON *pdehydrate_keep_time_4 = cJSON_GetObjectItem(pJson,"dehydrate_keep_time_4");
    obj.dehydrate_keep_time_4 = pdehydrate_keep_time_4->valueint;

    cJSON *prinse_water_level_5 = cJSON_GetObjectItem(pJson,"rinse_water_level_5");
    obj.rinse_water_level_5 = prinse_water_level_5->valueint;

    cJSON *prinse_speed_5 = cJSON_GetObjectItem(pJson,"rinse_speed_5");
    obj.rinse_speed_5 = prinse_speed_5->valueint;

    cJSON *prinse_on_time_5 = cJSON_GetObjectItem(pJson,"rinse_on_time_5");
    obj.rinse_on_time_5 = prinse_on_time_5->valueint;


    cJSON *prinse_off_time_5 = cJSON_GetObjectItem(pJson,"rinse_off_time_5");
    obj.rinse_off_time_5 = prinse_off_time_5->valueint;

    cJSON *prinse_time_5 = cJSON_GetObjectItem(pJson,"rinse_time_5");
    obj.rinse_time_5 = prinse_time_5->valueint;

    cJSON *prinse_isSpin_5 = cJSON_GetObjectItem(pJson,"rinse_isSpin_5");
    obj.rinse_isSpin_5 = prinse_isSpin_5->valueint;

    cJSON *pdehydrate_top_speed_5 = cJSON_GetObjectItem(pJson,"dehydrate_top_speed_5");
    obj.dehydrate_top_speed_5 = pdehydrate_top_speed_5->valueint;

    cJSON *pdehydrate_keep_time_5 = cJSON_GetObjectItem(pJson,"dehydrate_keep_time_5");
    obj.dehydrate_keep_time_5 = pdehydrate_keep_time_5->valueint;

    cJSON *pdehydrate_top_speed_in_wash = cJSON_GetObjectItem(pJson,"dehydrate_top_speed_in_wash");
    obj.dehydrate_top_speed_in_wash = pdehydrate_top_speed_in_wash->valueint;

    cJSON *pdehydrate_keep_time_in_wash = cJSON_GetObjectItem(pJson,"dehydrate_keep_time_in_wash");
    obj.dehydrate_keep_time_in_wash = pdehydrate_keep_time_in_wash->valueint;

    cJSON *pdehydrate_top_speed_in_final = cJSON_GetObjectItem(pJson,"dehydrate_top_speed_in_final");
    obj.dehydrate_top_speed_in_final = pdehydrate_top_speed_in_final->valueint;

    cJSON *pdehydrate_keep_time_in_final = cJSON_GetObjectItem(pJson,"dehydrate_keep_time_in_final");
    obj.dehydrate_keep_time_in_final = pdehydrate_keep_time_in_final->valueint;
    
    cJSON *pheatingOnTime = cJSON_GetObjectItem(pJson,"heatingOnTime");
    obj.heatingOnTime =  pheatingOnTime->valueint;


    cJSON *pdeploy_time = cJSON_GetObjectItem(pJson,"deploy_time");
    obj.deploy_time =  pdeploy_time->valueint;

     cJSON *pdoor_wash_time = cJSON_GetObjectItem(pJson,"door_wash_time");
    obj.door_wash_time = pdoor_wash_time->valueint;

    cJSON *pisDehydrate = cJSON_GetObjectItem(pJson,"isDehydrate");
    obj.isDehydrate = pisDehydrate->valueint;

    cJSON *pisDehydrateFinal = cJSON_GetObjectItem(pJson,"isDehydrateFinal");
    obj.isDehydrateFinal = pisDehydrateFinal->valueint;

    cJSON *pSpin_time = cJSON_GetObjectItem(pJson,"Spin_time");
    obj.Spin_time = pSpin_time->valueint;

    cJSON *pSpin_speed = cJSON_GetObjectItem(pJson,"Spin_speed");
    obj.Spin_speed = pSpin_speed->valueint;

    cJSON *pSpin_mid_time = cJSON_GetObjectItem(pJson,"Spin_mid_time");
    obj.Spin_mid_time = pSpin_mid_time->valueint;




    // int data_downmode = new Uint8Array(105);
    int tempInt = 0;
    int i = 0;
    // data_downmode[0] = 0xbb;
    // data_downmode[1] = 0xbb;
    // //总长度
    // data_downmode[2] = 0x00;
    // data_downmode[3] = 0x63;
    // //有效帧长
    // data_downmode[4] = 0x00;
    // data_downmode[5] = 0x63;

    //帧命令字
    data_downmode[i++] = 0x00;
    //soak water level
    tempInt = obj.soak_water_level;
    data_downmode[i++] = (tempInt >> 8);
    data_downmode[i++] = (tempInt & 0x0FF);

    //soak time
    data_downmode[i++] = obj.soak_time;
    //wash water level
    tempInt = obj.wash_water_level;
    data_downmode[i++] = tempInt >> 8;
    data_downmode[i++] = (tempInt & 0x0FF);
    //wash temp
    data_downmode[i++] = obj.wash_temp;
    //wash 1 step
    //wash speed
    data_downmode[i++] = obj.wash_1_speed;
    //wash on time
    data_downmode[i++] = obj.wash_1_on_time;
    //wash off time
    data_downmode[i++] = obj.wash_1_off_time;
    //wash time
    data_downmode[i++] = obj.wash_1_time;

    //wash 2 step,like 1 step
    data_downmode[i++] = obj.wash_2_speed;
    data_downmode[i++] = obj.wash_2_on_time;
    data_downmode[i++] = obj.wash_2_off_time;
    data_downmode[i++] = obj.wash_2_time;

    //wash 3 step,like 1 step
    data_downmode[i++] = obj.wash_3_speed;
    data_downmode[i++] = obj.wash_3_on_time;
    data_downmode[i++] = obj.wash_3_off_time;
    data_downmode[i++] = obj.wash_3_time;

    //check dehydrate in wash
    data_downmode[i++] = obj.isDehydrate;
    //dehydrate speed
    tempInt = obj.dehydrate_top_speed_in_wash;
    data_downmode[i++] = tempInt >> 8;
    data_downmode[i++] = tempInt & 0xFF;
    //dehydrate keep time
    tempInt = obj.dehydrate_keep_time_in_wash;
    data_downmode[i++] = tempInt >> 8;
    data_downmode[i++] = tempInt & 0xFF;

    //rinse state
    //rinse
    data_downmode[i++] = obj.rinse_times;

    //rinse state 1
    tempInt = obj.rinse_time_1;
    data_downmode[i++] = (tempInt >> 8);
    data_downmode[i++] = (tempInt & 0xFF);
    //rinse water level
    tempInt = obj.rinse_water_level_1;
    data_downmode[i++] = (tempInt >> 8);
    data_downmode[i++] = (tempInt & 0xFF);
    //rinse speed
    data_downmode[i++] = obj.rinse_speed_1;
    //rinse  on time
    data_downmode[i++] = obj.rinse_on_time_1;
    data_downmode[i++] = obj.rinse_off_time_1;

    //rinse state 2
    tempInt = obj.rinse_time_2;
    data_downmode[i++] = (tempInt >> 8);
    data_downmode[i++] = (tempInt & 0xFF);
    //rinse water level
    tempInt = obj.rinse_water_level_2;
    data_downmode[i++] = (tempInt >> 8);
    data_downmode[i++] = (tempInt & 0xFF);
    //rinse speed
    data_downmode[i++] = obj.rinse_speed_2;
    //rinse  on time
    data_downmode[i++] = obj.rinse_on_time_2;
    data_downmode[i++] = obj.rinse_off_time_2;

    //rinse state 3
    tempInt = obj.rinse_time_3;
    data_downmode[i++] = (tempInt >> 8);
    data_downmode[i++] = (tempInt & 0xFF);
    //rinse water level
    tempInt = obj.rinse_water_level_3;
    data_downmode[i++] = (tempInt >> 8);
    data_downmode[i++] = (tempInt & 0xFF);
    //rinse speed
    data_downmode[i++] = obj.rinse_speed_3;
    //rinse  on time
    data_downmode[i++] = obj.rinse_on_time_3;
    data_downmode[i++] = obj.rinse_off_time_3;

    //rinse state 4
    tempInt = obj.rinse_time_4;
    data_downmode[i++] = (tempInt >> 8);
    data_downmode[i++] = (tempInt & 0xFF);
    //rinse water level
    tempInt = obj.rinse_water_level_4;
    data_downmode[i++] = (tempInt >> 8);
    data_downmode[i++] = (tempInt & 0xFF);
    //rinse speed
    data_downmode[i++] = obj.rinse_speed_4;
    //rinse  on time
    data_downmode[i++] = obj.rinse_on_time_4;
    data_downmode[i++] = obj.rinse_off_time_4;

    //rinse state 5
    tempInt = obj.rinse_time_5;
    data_downmode[i++] = (tempInt >> 8);
    data_downmode[i++] = (tempInt & 0x0FF);
    //rinse water level
    tempInt = obj.rinse_water_level_5;
    data_downmode[i++] = (tempInt >> 8);
    data_downmode[i++] = (tempInt & 0xFF);
    //rinse speed
    data_downmode[i++] = obj.rinse_speed_5;
    //rinse  on time
    data_downmode[i++] = obj.rinse_on_time_5;
    data_downmode[i++] = obj.rinse_off_time_5;

    //dehydrate in rinse(  5 step )
    //step 1
    data_downmode[i++] = obj.rinse_isSpin_1;
    tempInt = obj.dehydrate_top_speed_1;
    //dehyrate RPM
    data_downmode[i++] = tempInt >> 8;
    data_downmode[i++] = (tempInt & 0xFF);
    //keep time
    tempInt = obj.dehydrate_keep_time_1;
    data_downmode[i++] = tempInt >> 8;
    data_downmode[i++] = (tempInt & 0xFF);

    //step 2
    data_downmode[i++] = obj.rinse_isSpin_2;
    tempInt = obj.dehydrate_top_speed_2;
    //dehyrate RPM
    data_downmode[i++] = tempInt >> 8;
    data_downmode[i++] = (tempInt & 0xFF);
    //keep time
    tempInt = obj.dehydrate_keep_time_2;
    data_downmode[i++] = tempInt >> 8;
    data_downmode[i++] = (tempInt & 0xFF);

    //step 3
    data_downmode[i++] = obj.rinse_isSpin_3;
    tempInt = obj.dehydrate_top_speed_3;
    //dehyrate RPM
    data_downmode[i++] = tempInt >> 8;
    data_downmode[i++] = (tempInt & 0xFF);
    //keep time
    tempInt = obj.dehydrate_keep_time_3;
    data_downmode[i++] = tempInt >> 8;
    data_downmode[i++] = (tempInt & 0xFF);

    //step 4
    data_downmode[i++] = obj.rinse_isSpin_4;
    tempInt = obj.dehydrate_top_speed_4;
    //dehyrate RPM
    data_downmode[i++] = tempInt >> 4;
    data_downmode[i++] = (tempInt & 0xFF);
    //keep time
    tempInt = obj.dehydrate_keep_time_4;
    data_downmode[i++] = tempInt >> 8;
    data_downmode[i++] = (tempInt & 0xFF);

    //step 5
    data_downmode[i++] = obj.rinse_isSpin_5;
    tempInt = obj.dehydrate_top_speed_5;
    //dehyrate RPM
    data_downmode[i++] = tempInt >> 8;
    data_downmode[i++] = (tempInt & 0xFF);
    //keep time
    tempInt = obj.dehydrate_keep_time_5;
    data_downmode[i++] = tempInt >> 8;
    data_downmode[i++] = (tempInt & 0xFF);

    //final dehydrate   (just dehydrate)
    //if dehydrate  state
    data_downmode[i++] = obj.isDehydrateFinal;
    //RPM
    tempInt = obj.dehydrate_top_speed_in_final;
    data_downmode[i++] = tempInt >> 8;
    data_downmode[i++] = tempInt & 0xFF;
    //time
    tempInt = obj.dehydrate_keep_time_in_final;
    data_downmode[i++] = tempInt >> 8;
    data_downmode[i++] = tempInt & 0xFF;

    //spin time
    data_downmode[i++] = 0x00;

    //spin speed
    data_downmode[i++] = 0x00;
    data_downmode[i++] = 0x00;

    //spin mid time
    data_downmode[i++] = 0x00;

    //heat on time
    data_downmode[i++] = obj.heatingOnTime;

    //deploy time
    tempInt = obj.deploy_time;
    data_downmode[i++] = tempInt >> 8;
    data_downmode[i++] = tempInt & 0xFF;

    data_downmode[i++] = obj.door_wash_time;

    printf("serial len %d\n",i );
    
    int c = 0;

    printf("serial data:\n");
    for (c = 0; c < i; c++)
    {
        printf("%02x ", data_downmode[c]);
    }

    printf("\n");


    return i;




}

int encodeseril(serillen)
{
    unsigned char *input_string;
    unsigned char *encrypt_string;
    AES_KEY aes;
    unsigned int i;

    unsigned char key[AES_BLOCK_SIZE];        // AES_BLOCK_SIZE = 16
    unsigned char iv[AES_BLOCK_SIZE];        // init vector

    // set the encryption length
    int enlen = 0;
    if ((serillen + 1) % AES_BLOCK_SIZE == 0) {
        enlen = serillen + 1;
    } else {
        enlen = ((serillen + 1) / AES_BLOCK_SIZE + 1) * AES_BLOCK_SIZE;
    }

    printf("len :%d\n", enlen);

    // set the input string
    input_string = (unsigned char*)calloc(enlen, sizeof(unsigned char));
    if (input_string == NULL) {
        fprintf(stderr, "Unable to allocate memory for input_string\n");
        return -1;
    }



    int t = 0;

    printf("en ---- :serial data:\n");
    for (t = 0; t < serillen; t++)
    {
        printf("%02x ", data_downmode[t]);
    }

    printf("\n");


    memcpy(input_string, data_downmode, serillen);


    printf("en ---- :input_string data:\n");
    for (t = 0; t < serillen; t++)
    {
        printf("%02x ", input_string[t]);
    }

    printf("\n");


    // alloc encrypt_string
    encrypt_string = (unsigned char*)calloc(enlen, sizeof(unsigned char));    
    if (encrypt_string == NULL) {
        fprintf(stderr, "Unable to allocate memory for encrypt_string\n");
    }
 


    // Generate AES 128-bit key
    for (i=0; i<16; ++i) {
        key[i] = 32 + i;
    }
    // Set encryption key
    for (i=0; i<AES_BLOCK_SIZE; ++i) {
        iv[i] = 0;
    }
    if (AES_set_encrypt_key(key, 128, &aes) < 0) {
        fprintf(stderr, "Unable to set encryption key in AES\n");
        return -1;
    }



    // encrypt (iv will change)
    AES_cbc_encrypt(input_string, encrypt_string , enlen, &aes, iv, AES_ENCRYPT);
 
   //enbase64
    unsigned char enbase64[4096] = {0};
    base64_encode(encrypt_string, enlen,enbase64);
    printf("enbase64 :\n%s\n", enbase64);



    return 0;
}




int main(int argc, char const *argv[])
{
    int len = 0;    
    len = set_mode_down((unsigned char *)argv[1]);

	if(len>0)
	{
    	encodeseril(len);
	}




    return 0;
}
